package f_socketChat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
	
	private List<MyChanel> all= new ArrayList<MyChanel>();
	
	public static void main(String[] args) throws IOException {
		//开启服务器对象
		new Server().start();
	}
	
	/**
	 * 开启服务器
	 * @throws IOException 
	 */
	private void start() throws IOException {
		//1 创建服务区 指定端口 ServerSocket(int port) 
		ServerSocket server = new ServerSocket(9999);
		 // 2 接收客户端连接 阻塞式  
		while (true) {//死循环 一个accept() 一个客户端  
			Socket client = server.accept();
			System.out.println("有人连接");
			MyChanel chanel = new MyChanel(client);
			System.out.println("创建频道");
			//加入到容器中统一管理
			all.add(chanel);
			//一条道路(线程)
			new Thread(chanel).start();
		}
		
		
	}




	/**
	 * 一个客户端一个道路(线程)
	 * 1.输入流
	 * 2.输出流
	 * 3.接收数据
	 * 4.发送数据
	 * @author Y
	 *
	 */
	public class MyChanel implements Runnable {
		//输入流
		private DataInputStream dis;
		//输出流
		private DataOutputStream dos;
		//运行状态
		private boolean isRunning=true;
		//用户名
		private String name;
		
		/*
		 * 初始化频道
		 */
		public MyChanel(Socket client) {
			try {
				dis = new DataInputStream(client.getInputStream());
				dos=new DataOutputStream(client.getOutputStream());
				//用户名
				this.name=dis.readUTF();
				System.out.println(name+"连入聊天室");
				this.send("欢迎你 进入聊天室");
				sendOthers(this.name+"进入聊天室",true);
				
			} catch (IOException e) {
				System.err.println("发生异常:"+e.getMessage()+e);
				//释放资源
				CloseUtil.closeAll(dis,dos);
				//关闭频道状态
				isRunning = false;
			}
		
		
		}
		
		/**
		 * 读取数据
		 * @return
		 */
		private String receive(){
			//消息
			String msg = "";
			try {
				//接收消息
				msg=dis.readUTF();
			} catch (IOException e) {
				System.err.println("服务器接收信息异常:"+e.getMessage());
				CloseUtil.closeAll(dis);
				isRunning=false;
				//移除自身
				all.remove(this);
			}
			return msg;
		}
		
		/**
		 * 发送给其他客户端
		 * @param string
		 * @param b
		 */
		private void sendOthers(String msg, boolean sys) {
			System.out.println(msg);
			//是否为私聊 约定
			if (msg!=null && msg.startsWith("@") && msg.indexOf(":") > -1) {//表示私聊
				//截取私聊名字
				String name =msg.substring(1, msg.indexOf(":"));
				//截取私聊内容
				String content =msg.substring(msg.indexOf(":")+1);
				//获取所有频道的name
				for (MyChanel other : all) {
					//判断接受对象是否存在
					if (other.name.equals(name)) {
						//给接受对象发送 消息
						other.send(this.name+" 对您悄悄说: "+content);
					}
				}
				
			} else {
				//遍历容器
				for (MyChanel other : all) {
					if (other == this) {
						continue;
					}
					if (sys) {//系统消息
						//发送 系统消息 给其他客户端
						other.send("系统消息:"+msg);
					} else {
						//发送给其他客户端
						other.send(this.name+":"+msg);
					}
				}
			}
		}
		
		/**
		 * 发送数据
		 * @param string
		 */
		private void send(String msg) {
			if (null == msg && !"".equals(msg)) {
				return;
			}
			try {
				//写入数据
				dos.writeUTF(msg);
				//强制刷新
				dos.flush();
			} catch (IOException e) {
				CloseUtil.closeAll(dos);
				isRunning=false;
				all.remove(this);//移除自身
			}
		}

		@Override
		public void run() {
			//
			while (isRunning) {
				sendOthers(receive(), false);
			}
		}

	}


}
